package admin

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"strings"
	"time"
	"xianzhi/utils"
	"xianzhi/utils/wechat"
)

type UploadController struct {
	BaseController
}

func (c *UploadController) Prepare() {
	c.EnableXSRF = false
}

// 上传到腾讯云对象存储
func (c *UploadController) Tencent() {
	res := struct {
		Errno int      `json:"errno"`
		Msg   string   `json:"msg"`
		Data  []string `json:"data"`
	}{}
	fileList, err := c.GetFiles("editorFile")
	if err != nil {
		res.Errno = 1
		res.Msg = "获取文件失败" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	maxSize := int64(2 << 20)
	for _, h := range fileList {
		if h.Size > maxSize {
			res.Errno = 1
			res.Msg = "上传的每个文件大小不能超过2M"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
	}
	bucketDomain := beego.AppConfig.String("bucketdomain")
	for _, fh := range fileList {
		f, err := fh.Open()
		if err != nil {
			res.Errno = 1
			res.Msg = "有文件上传失败"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
		ext := path.Ext(fh.Filename)
		defer f.Close()
		objKey := "admin/" + time.Now().Format("20060102") + "/" + utils.Encode(fmt.Sprintf("%d", time.Now().UnixNano())) + ext
		c := utils.GetStorageObj()
		c.Object.Put(context.Background(), objKey, f, nil)
		res.Data = append(res.Data, fmt.Sprintf("%s/%s", bucketDomain, objKey))
	}
	res.Errno = 0
	c.Data["json"] = &res
	c.ServeJSON()
}

// 上传永久图片素材
func (c *UploadController) Material() {
	var res *utils.ResJsonStruct
	fileList, err := c.GetFiles("mediaFile")
	if err != nil {
		res = utils.ResJson(0, "无法获取到文件:"+err.Error(), "")
		c.Data["json"] = res
		c.ServeJSON()
		return
	}
	maxSize := int64(2 << 20)
	for _, h := range fileList {
		if h.Size > maxSize {
			res = utils.ResJson(0, "上传文件大小不能超过2M:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
	}
	bucketDomain := beego.AppConfig.String("bucketdomain")
	accessToken := wechat.GetAccessToken("xianzhi")
	url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=image", accessToken)
	for _, fh := range fileList {

		f, err := fh.Open()
		if err != nil {
			res = utils.ResJson(0, "文件上传失败:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}

		body := &bytes.Buffer{}
		writer := multipart.NewWriter(body)
		part, err := writer.CreateFormFile("media", fh.Filename)
		if err != nil {
			res = utils.ResJson(0, "文件上传失败:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		_, err = io.Copy(part, f)
		if err != nil {
			res = utils.ResJson(0, "文件上传失败:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		contentType := writer.FormDataContentType()
		writer.Close()
		resp, err := http.Post(url, contentType, body)
		if err != nil {
			res = utils.ResJson(0, "文件上传失败:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		defer resp.Body.Close()
		respBody, err := ioutil.ReadAll(resp.Body)
		materialRes := struct {
			Errcode int    `json:"errcode"`
			Errmsg  string `json:"errmsg"`
			MediaId string `json:"media_id"`
			Url     string `json:"url"`
		}{}
		err = json.Unmarshal(respBody, &materialRes)
		if err != nil {
			res = utils.ResJson(0, "文件上传失败:"+err.Error(), "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		if materialRes.Errcode != 0 {
			res = utils.ResJson(0, "文件上传失败:"+materialRes.Errmsg, "")
			c.Data["json"] = res
			c.ServeJSON()
			return
		}
		f.Close()

		f, err = fh.Open()
		ext := path.Ext(fh.Filename)
		objKey := "admin/" + time.Now().Format("20060102") + "/" + utils.Encode(fmt.Sprintf("%d", time.Now().UnixNano())) + ext
		storageObj := utils.GetStorageObj()
		storageObj.Object.Put(context.Background(), objKey, f, nil)

		data := struct {
			MediaId string `json:"media_id"`
			MediaUrl     string `json:"media_url"`
			LocalUrl string `json:"local_url"`
		}{
			MediaId: materialRes.MediaId,
			MediaUrl: materialRes.Url,
			LocalUrl: fmt.Sprintf("%s/%s", bucketDomain, objKey),
		}
		f.Close()

		res = utils.ResJson(1, "success", data)
	}
	c.Data["json"] = res
	c.ServeJSON()
}

// 单个文件上传
func (c *UploadController) SingleFile() {
	res := struct {
		Jsonrpc string `json:"jsonrpc"`
		Code    int    `json:"code"`
		Result  string `json:"result"`
		Msg     string `json:"msg"`
		Id      string `json:"id"`
	}{}
	res.Jsonrpc = "2.0"
	f, h, err := c.GetFile("excel_file")
	if err != nil {
		res.Code = 0
		res.Msg = "上传文件出错:" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	defer f.Close()
	maxSize := int64(2 << 20)
	if h.Size > maxSize {
		res.Code = 0
		res.Msg = "上传文件大小不能超过2M"
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	ext := path.Ext(h.Filename)
	t := time.Now().Format("20060102")
	d := "./static/upload/" + t
	_, err = os.Stat(d)
	if err != nil {
		os.MkdirAll(d, os.ModePerm)
	}
	n := fmt.Sprintf("%d", time.Now().UnixNano())
	toFile := d + "/" + utils.Encode(n) + ext
	err = c.SaveToFile("excel_file", toFile)
	if err != nil {
		res.Code = 0
		res.Msg = "保存文件出错" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	res.Code = 1
	res.Msg = "success"
	res.Result = strings.TrimLeft(toFile, ".")
	c.Data["json"] = &res
	c.ServeJSON()
}

/*
// 多个文件上传
func (c *UploadController) Editor() {
	res := struct{
		Errno int `json:"errno"`
		Msg string `json:"msg"`
		Data []string `json:"data"`
	}{}
	fileList, err := c.GetFiles("editorFile")
	if err != nil {
		res.Errno = 1
		res.Msg = "获取文件失败" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	maxSize := int64(2 << 20)
	for _, h := range fileList {
		if h.Size > maxSize {
			res.Errno = 1
			res.Msg = "上传的每个文件大小不能超过2M"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
	}
	for _, fh := range fileList {
		f, err := fh.Open()
		if err != nil {
			res.Errno = 1
			res.Msg = "有文件上传失败"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
		d := "./static/upload/" + time.Now().Format("20060102")
		_, err = os.Stat(d)
		if err != nil {
			os.MkdirAll(d, os.ModePerm)
		}
		logs.Info(fh.Filename)
		ext := path.Ext(fh.Filename)
		n := fmt.Sprintf("%d", time.Now().UnixNano())
		toFile := d + "/" + utils.Encode(n) + ext
		dst, err := os.OpenFile(toFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
		if err != nil {
			res.Errno = 1
			res.Msg = "有文件上传失败"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
		_, err = io.Copy(dst, f)
		if err != nil {
			res.Errno = 1
			res.Msg = "有文件上传失败"
			c.Data["json"] = &res
			c.ServeJSON()
			return
		}
		res.Data = append(res.Data, strings.TrimLeft(toFile, "."))
		f.Close()
		dst.Close()
	}
	res.Errno = 0
	c.Data["json"] = &res
	c.ServeJSON()
}*/

/*
// 单个文件上传
func (c *UploadController) Editor1() {
	res := struct{
		Errno int `json:"errno"`
		Msg string `json:"msg"`
		Data []string `json:"data"`
	}{}
	f, h, err := c.GetFile("editorFile")
	if err != nil {
		res.Errno = 1
		res.Msg = "上传文件出错" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	defer f.Close()
	maxSize := int64(2 << 20)
	if h.Size > maxSize {
		res.Errno = 1
		res.Msg = "上传文件大小不能超过2M"
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	ext := path.Ext(h.Filename)
	enableExt := map[string]bool{
		".jpg": true,
		".JPG": true,
		".jpeg": true,
		".JPEG": true,
		".png": true,
		".PNG": true,
		".gif": true,
		".GIF": true,
	}
	_, ok := enableExt[ext]
	if !ok {
		res.Errno = 1
		res.Msg = "上传文件格式不正确"
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	t := time.Now().Format("20060102")
	d := "./static/upload/" + t
	_, err = os.Stat(d)
	if err != nil {
		os.MkdirAll(d, os.ModePerm)
	}
	n := fmt.Sprintf("%d", time.Now().UnixNano())
	toFile := d + "/" + utils.Encode(n) + ext
	err = c.SaveToFile("editorFile", toFile)
	if err != nil {
		res.Errno = 1
		res.Msg = "上传文件出错" + err.Error()
		c.Data["json"] = &res
		c.ServeJSON()
		return
	}
	res.Errno = 0
	res.Data = append(res.Data, strings.TrimLeft(toFile, "."))
	c.Data["json"] = &res
	c.ServeJSON()
}*/
